namespace detail {
template<typename Sender, typename Prdicate, typename MessageType = typename Sender::value_type>
class filter_impl {
    public:
        using value_type = MessageType;

        filter_impl(Sender &&sender, Predicate predicate)
            : m_sender(std::move(sender))
            , m_predicate(predicate)
        {
        }

        template <typename EmitFunction>
        void on_message(EmitFunction emit)
        {
            m_emit = emit;
            m_sender.on_message(
                [this] (MessageType &&message)
                    {
                        process_message(std::move(message));
                    }
                );
        }

        void process_message(MessageType &&message) const
        {
            if (m_emit && std::invoke(m_predicate, message)) {
                m_emit(std::move(message));
            }
        }
    private:
        Sender m_sender;
        Predicate m_predicate;
        std::function<void(MessageType&&)> m_emit;

};
template <typename Predicate>
    struct filter_helper {
        Predicate predicate;
    };
}

